/**
 * @file 2.4.1.cc
 * @author your name (you@domain.com)
 * @brief 2.4.1 const的引用（对常量的引用）
 * @version 0.1
 * @date 2021-12-24
 * 
 * @copyright Copyright (c) 2021
 * 
 */
#include <iostream>

int main()
{
    const int ci = 1024;
    const int &r1 = ci; // 正确，引用r1及其对应的对象ci都是int型常量
    // r1 = 42; // 错误，r1是对常量的引用
    // int &r2 = ci; // 错误，试图让一个非常量引用r2指向一个常量对象ci

    // 初始化常量引用时，允许用任意表达式作为初始值，只要表达式的结果可以转换成引用的类型即可
    int i = 42;
    const int &ri1 = i;
    const int &ri2 = 42;
    const int &ri3 = ri1 * 2;
    // int &ri4 = ri1 * 2; // 错误，ri4是一个普通的非常量引用，不能用ri1常量引用初始化

    // 临时量对象
    // 所谓临时量对象就是当编译器需要一个空间来暂存表达式的求值结果时临时创建的一个未命名的对象
    double dVal = 3.14;
    const int &ri = dVal; // 让double对象绑定到int型常量引用ri上，实际上ri绑定的是一个编译器创造的临时量对象
    // 编译器把上述代码变成了如下形式：
    // const int temp = dVal; // 由双精度浮点数生成一个临时的整型常量
    // const int &ri = temp; // 让ri绑定这个临时量
    int ii = 3;
    const int &ri0 = ii;
    // ri0 = 6; // 错误，因为常量引用限定了引用的操作，规定了这个引用时常量，所以不能通过修改ri0来改变对象ii
    ii = 8; // 正确，因为ii不是const修饰的常量，所以可以修改
    std::cout << ri0 << std::endl; // 打印8，因为ri0绑定了ii

    

    return 0;
}